﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    public Texture2D[] RoomTextures;
    public UnityEngine.UI.RawImage RoomImageTemplate;
    
    //关卡维度
    public int SizeX;
    public int SizeY;

    public UnityEngine.UI.RawImage[,] RoomImages;

    //房间数据
    public class RoomData
    {
        int[,] _Data;
        public RoomData(int x, int y)
        {
            _Data = new int[x, y];
        }
       
        public int this[Vector2Int index]
        {
            get { return _Data[index.x,index.y]; }
            set { _Data[index.x, index.y] = value; }
        }
        public int this[int x, int y]
        {
            get { return _Data[x, y]; }
            set { _Data[x, y] = value; }
        }
    }

    RoomData room_data;


    void Start()
    {
        room_data = new RoomData(SizeX, SizeY);
        PrepareImage();
        ResetRooms();
    }

    public void ResetRooms()
    {
        GenerateRooms();
        DisplayRoomImages();
    }

    //生成房间
    void GenerateRooms()
    {
        //初始化所有房间为0
        for (int x = 0; x < SizeX; x++)
            for (int y = 0; y < SizeY; y++)
                room_data[x, y] = 0;

        //决定初始房间的X
        int StartRoomX = Random.Range(0, SizeX);

        //当前房间设为初始房间
        Vector2Int PresentRoom = new Vector2Int(StartRoomX, SizeY-1);
        room_data[PresentRoom] = 1;

        while (true)//循环直至到出口
        {
            //计算下一个房间
            PresentRoom = DecideNextSolutionPathRoom(PresentRoom);
            //Debug.Log(PresentRoom);
            if (PresentRoom.y < 0)//如果超界，则说明到出口了
                break;
        }

        //看是否有蛇洞
        for(int x=0;x<SizeX;x++)
        {
            List<int> SnakeRooms = new List<int>();

            for (int y = 0; y < SizeY; y++)
            {
                if (room_data[x, y] == 0)//是0则添加
                    SnakeRooms.Add(y);
                else//中断
                {
                    if (SnakeRooms.Count >= 3)
                        break;
                    else
                    {
                        SnakeRooms.Clear();
                        continue;
                    }
                }
            }

            if (SnakeRooms.Count >= 3)//符合蛇洞的出现条件
            {
                room_data[x, SnakeRooms[0]] = 9;
                for(int y= 1;y< SnakeRooms.Count-1;y++)
                    room_data[x, SnakeRooms[0]+y] = 8;
                room_data[x, SnakeRooms[SnakeRooms.Count - 1]] = 7;
            }
        }
        
    }
    //决定下一个,参数是这个房间，返回下一个房间
    Vector2Int DecideNextSolutionPathRoom(Vector2Int ThisRoom)
    {
        //首先随机决定前进的方向*************************************************************

        List<Vector2Int> MoveDirectionOptions = new List<Vector2Int>(); //可能的移动方向
        List<float> Weights = new List<float>();                        //可能的移动方向的权重
        
        //判断左右能否移动
        for(int d=0;d<2;d++)
        {
            Vector2Int Direction = new Vector2Int(d * 2 - 1, 0);
            //判断是否超界：
            if (((ThisRoom + Direction).x < 0) || ((ThisRoom + Direction).x >= SizeX))
                continue;
            //判断有没有初始化，不为0说明已经在SolutionPath中了
            if (room_data[ThisRoom + Direction] > 0)
                continue;

            //检测通过，加上这个可能性和权重
            MoveDirectionOptions.Add(Direction);
            Weights.Add(1.0f*SizeX/2);
        }

        //判断是否能下
        if ((ThisRoom.y == (SizeY - 1))  //如果是最后一行，则能下（下表示出口）
            || (room_data[ThisRoom] != 3)) //否则看是不是3。3是没有下口的
        {
            MoveDirectionOptions.Add(new Vector2Int(0,-1));
            Weights.Add(1.0f);
        }

        //最后随机出结果
        Vector2Int MoveDirection = MoveDirectionOptions[WeightedRandom(Weights)];

        //然后实行移动*************************************************************
        Vector2Int NextRoom = ThisRoom + MoveDirection;
        if (MoveDirection==new Vector2Int(0,-1))//向下
        {
            if (ThisRoom.y != 0)//不是底层
            {
                room_data[ThisRoom] = 2;//将这个房间覆写为2
                room_data[NextRoom] = 3;//将下个房间定为3
            }
        }
        else
            room_data[NextRoom] = 1;//将下个房间定为1

        return NextRoom;
    }
    //加权随机
    int WeightedRandom(List<float> Weights)
    {
        float WeightSum = 0;
        foreach(float w in Weights)
            WeightSum += w;
        float RandomNumber = Random.Range(0, WeightSum);
        for (int i = 0; i < Weights.Count; i++)
        {
            if (RandomNumber < Weights[i])
                return i;
            else
                RandomNumber -= Weights[i];
        }
        return -1;

    }

    void PrepareImage()
    {
        RoomImages = new UnityEngine.UI.RawImage[SizeX, SizeY];
        for (int x = 0; x < SizeX; x++)
            for (int y = 0; y < SizeY; y++)
            {
                RoomImages[x,y] = Instantiate(RoomImageTemplate.gameObject).GetComponent<UnityEngine.UI.RawImage>();
                RoomImages[x, y].rectTransform.SetParent(RoomImageTemplate.rectTransform.parent);
                
                RoomImages[x, y].rectTransform.anchoredPosition = new Vector2((1.0f * x - 0.5f * SizeX + 0.5f) * 100, (1.0f * y - 0.5f * SizeY + 0.5f) * 60);
            }
        RoomImageTemplate.gameObject.SetActive(false);
    }

    //显示出房间图片
    void DisplayRoomImages()
    {
        for (int x = 0; x < SizeX; x++)
            for (int y = 0; y < SizeY; y++)
                RoomImages[x, y].texture = RoomTextures[room_data[x, y]];
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
